<?php

namespace App\common\service;

use think\facade\Db;
use think\facade\Cache;
use think\facade\Request;
use app\common\utils\JsonResponse;

class UserService
{
    public function deviceIdLogin($params) {
        // 看看设备是否存在
        $device = Db::name('device')->where('device_id', $params['device_id'])->find();

        if (!$device) {
            // 设备不存在，注册设备并生成虚拟手机号
            $phone = $this->generateUniquePhoneNumber();
            Db::startTrans();
            try {
                // 创建虚拟用户
                $userId = $this->registerUser($phone);

                if (!$userId) {
                    Db::rollBack();
                    return JsonResponse::error('设备注册失败，请稍后再试');
                }

                // 注册设备信息
                Db::name('device')->insertGetId(['device_id'=>$params['device_id'],
                    'device_name'=>$params['device_name'] ?? "未知设备",
                    'device_model'=>$params['device_model'] ?? "未知型号",
                    'user_id'=>$userId,'register_time'=>date('Y-m-d H:i:s')]);
//                $device->save();

                // 生成并保存新的 token 时效5年 $params['device_id'], , strtotime("+5 years")
                $token = $this->generateToken($userId, $phone);
                if (!$token) {
                    Db::rollBack();
                    return JsonResponse::error('登录失败，请重新登录');;
                }
                //记录登录时间
                if($this->recordtime($userId)===false){
                    Db::rollBack();
                    JsonResponse::error('登录失败');
                }
                if($token){
                    //user_token
                    Db::name('user_token')->insert(['user_id' => $userId,'token' => $token,'expire_time' => strtotime("+15 days")]);
                    Cache::set('user_token_' . $token, $userId, 86400*15);
                }
                //记录登录时间
                if($this->recordtime($userId)===false){
                    Db::rollBack();
                    JsonResponse::error('登录失败');
                }

                Db::commit();
                
                return JsonResponse::success(['token' => $token, 'user_id' => $userId, 'is_login'=>1]);

            } catch (\Exception $e) {
                Db::rollBack();
                return JsonResponse::error('系统异常，请稍后再试');
            }
        } else {
            // 设备已注册，检查是否有用户绑定
            $userId = $device['user_id'];
            Db::startTrans();
            if (!$userId) {
                Db::rollBack();
                return JsonResponse::error('设备绑定用户');
            }
            // 获取用户手机号
            $phone= Db::name('user')->where('id', $userId)->whereNull('delete_time')->value('phone');
            if (!$phone) {
                Db::rollBack();
                return JsonResponse::error('用户信息不存在');
            }

            // 生成并返回新的 token $params['device_id'],
            $token = $this->generateToken($userId, $phone);
//            if($token){
//                Db::name('user_token')->insert(['user_id' => $userId,'token' => $token,'expire_time' => strtotime("+15 days")]);
//                Cache::set('user_token_' . $token, $userId, 86400*15);
//            }
            //记录登录时间
            if($this->recordtime($userId)===false){
                Db::rollBack();
                JsonResponse::error('登录失败');
            }
            Db::commit();
            return $token ? JsonResponse::success(['token' => $token, 'user_id' => $userId, 'is_login'=>1]) : JsonResponse::error('登录失败');
        }
    }

    private function recordtime($userId)
    {
        if(Db::name('user')->where('id', $userId)->update(['last_login_time' => time(),'last_login_ip'   => request()->ip()])===false){
            return false;
        }
        return true;
    }

    private function registerUser($phone)
    {
        $logdata = [
            'username' => $this->makeNewUserName(substr($phone, -4)),
            'password' => md5(substr($phone, -6)),
            'avatar' => 'https://sanyanhu.oss-cn-shenzhen.aliyuncs.com/whiteFoxAI/logo@3x.png',
            'phone' => $phone,
            'create_time'=>time(),
            'update_time'=>time()
        ];

        return Db::name('user')->insertGetId($logdata);
    }
    private function makeNewUserName($n = 0)
    {
        //规则：s + 随机数 + 手机尾号4位 + 随机字母两个
        if (empty($n)) $n = rand(1000, 9999);
        $numArr = str_split('0123456789');
        $strArr = str_split('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ');
        $randStr = array_rand($strArr, 2);
        $randNum = array_rand($numArr);
        $name = 's' . $numArr[$randNum] . $n . $strArr[$randStr[0]] . $strArr[$randStr[1]];
        return $name;
    }
    // 生成唯一的虚拟手机号
    private function generateUniquePhoneNumber() {
        $attempts = 0;
        $maxAttempts = 10;

        while ($attempts < $maxAttempts) {
            $phone = $this->getUniqueCode(11, 2, 98);

            // 检查数据库中是否已存在该手机号
            $exists = Db::name('user')->where('phone', $phone)->count();
            //  User::query()->where('phone', $phone)->exists();
            if (!$exists) {
                return $phone;
            }

            $attempts++;
        }

        return false; // 如果达到最大尝试次数仍未找到唯一手机号，返回 false
    }

    /**
     * 生成唯一随机码(并非绝对唯一，可以加时间戳前缀)
     *
     * @param int $length 随机码长度
     * @param string $prefix 前缀
     * @return string 生成的唯一随机码
     */
    private function getUniqueCode($length = 8, $character_type=1, $prefix = '') {
        if (empty($length)) $length = 8;
        if ($character_type == 1) {
            $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
        } elseif($character_type == 2) {
            $characters = '0123456789';
        } elseif ($character_type == 3) {
            $characters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
        } elseif ($character_type == 4) {
            $characters = '0123456789abcdefghijklmnopqrstuvwxyz';
        }

        $charactersLength = strlen($characters);
        $randomString = '';

        // 计算随机部分的长度
        $prefixLength = strlen($prefix);
        $randomPartLength = $length - $prefixLength;

        // 生成随机字符串
        for ($i = 0; $i < $randomPartLength; $i++) {
            $randomString .= $characters[random_int(0, $charactersLength - 1)];
        }

        return $prefix . $randomString;
    }

    private function generateToken($userId, $phone, $expiry=0, $login_type=1, $token='')
    {
        $user_tokens = Db::name('user_token');
        // 看看有没有有效的token
        $payload = [
            'user_id' => $userId,
//            'phone' => $phone,
            'status' => 1,
        ];
        $res = $user_tokens->where($payload)->find();
        if (!empty($res['expire_time']) && $res['expire_time'] > time() && !empty($res['token'])) {
            return $res['token'];
        }

        if (empty($token)) $token = md5(uniqid() . $phone);
        if (empty($expiry)) $expiry = strtotime("+15 days");
        $payload['token'] = $token;
        $payload['expire_time'] = $expiry;

        return $user_tokens->insertGetId($payload) ? $token : false;
    }
}
